package com.bodystm.algorithm;
/*Rate of rise and fall */
/**
* @describe: Resampling, it will provide the values in an array
* @param: old sampling rate (ms), new sampling rate (ms), pointer of the resampling array
*         nChannel:指定用几号通道进行工作
* @return: 1 indicates no resampled data is added and means either the program is initializing
*   or resampling process is in snyc with sampling frequency, if return is an integer value, it means that the the same number of resampled value is added.
*   negative numbers means this number of points needs to be skipped, and no new value is added to the buffer.
*   Changed by liuyue 2018/1/2
*       0:  使用该点
*       -1: 跳过该点
*       >0: 需要添加的点数
*       -2: 参数错误
*   End Change
* @author: Siyang Liang
* @date: 2017/07/07
*/
public class MathTools {
	//由于各个数据接收时都有各自的MathTools实例，所以这里可以设置为1，调用时channelID设置为0即可
	private static final int ResampSupportChannel=1;//"BOdystmDEVMax";
	double Ratio[]=new double[ResampSupportChannel], Progress[]=new double[ResampSupportChannel],Pace,Adjust[] =new double[ResampSupportChannel];
	int status[] = new int[ResampSupportChannel];
	double Seg[][] = new double[ResampSupportChannel][2];
	double Remain[] = new double[ResampSupportChannel];
	int nInitRemain[] = new int[ResampSupportChannel];
	double Step[]= new double[ResampSupportChannel], diff[]= new double[ResampSupportChannel], count[] = new double[ResampSupportChannel];
	public int Resampling(float OldF, float NewF, double[] ResValue, double Data, int nChannel)
	{
	    if (nChannel >= ResampSupportChannel || OldF <= 0.0000001 || NewF <= 0.0000001)
	        return -2;
	    double slop;
	    int i;

	    if (nInitRemain[nChannel] == 0)
	    {
	        Remain[nChannel] = OldF;
	        nInitRemain[nChannel] = 1;
	    }

	    if (status[nChannel] < 2) //initialization
	    {
	        Seg[nChannel][0] = Seg[nChannel][1];
	        Seg[nChannel][1] = Data;
	        status[nChannel]++;
	        if (status[nChannel] != 2) //make sure that at least two values has been added to the Segment
	        {
//	            *ResValue = Data; //always return the first value while the program is initializing
	            count[nChannel] = OldF;
	            return 0;
	        }
	        Ratio[nChannel] = NewF / OldF;
	    }
	    else
	    {

	        Seg[nChannel][0] = Seg[nChannel][1];
	        Seg[nChannel][1] = Data;
	        Ratio[nChannel] = (NewF) / Remain[nChannel];
	    }

	    if (Ratio[nChannel] < 1) //increase sampling rate
	    {
	        Step[nChannel] = 1 / Ratio[nChannel];
	        slop = (Seg[nChannel][1] - Seg[nChannel][0]) / OldF; //slop between the two data points
//	        for (i = 0; i < (int)(Step[nChannel]); i++)
//	        {
//	            *(ResValue + i) = ((i + 1)*NewF - diff[nChannel])*slop + Seg[nChannel][0];
//	        }
	        diff[nChannel] = (Step[nChannel] - (int)(Step[nChannel]))*NewF;
	        Remain[nChannel] = diff[nChannel] + OldF; //remaining time bewteen next sampling point

	        return (int)(Step[nChannel]) - 1;
	    }
	    else if (Ratio[nChannel] > 1)	//lowering sampling rate
	    {
	        Progress[nChannel] = count[nChannel] / (NewF);
	        if (Progress[nChannel] < 1) //not reaching resampling point
	        {
	            count[nChannel] += OldF;
	            return -1;
	        }
	        else
	        {
	            diff[nChannel] = OldF - (Progress[nChannel] - (int)(Progress[nChannel]))*NewF;
	            slop = (Seg[nChannel][1] - Seg[nChannel][0]) / OldF;
//	            *ResValue = diff[nChannel]*slop + Seg[nChannel][0];
	            //Adjust = OldF - diff;
	            count[nChannel] = OldF - diff[nChannel] + OldF;
	            return 0;
	        }
	    }
	    else
	    {
//	        *ResValue = Data;
	        Adjust[nChannel] = 0;
	        Remain[nChannel] = OldF;
	        return 0;
	    }
	}
	
	/*
	 * Brief: 两个数的最小公倍数(lcm)算法
	 * Params:
	 *      a:
	 *      b:
	 * Return:
	 *      两个数的最小公倍数
	 * Author:
	 *      2018/1/1
	 */
	int lcm(int a, int b)
	{
	    int t;
	    if (a>b)
	    {
	        t = a;
	        a = b;
	        b = t;
	    }
	    for (t = a; t%b!=0; t += a){};
	    return t;
	}

	/*
	 * Brief: n个数的最小公倍数算法,求出头两个的最小公倍数,再将欺和大三个数求最小公倍数直到数组末尾,这样产生一个递归的求nlcm的算法
	 * Params:
	 *      参数为数组的指针和数组的大小(需要计算的数的个数)
	 * Return:
	 *      n个数的最小公倍数
	 * Author:
	 *      2018/1/1
	 */
	int nlcm(int []a, int n)
	{
	    int nK = 1;
	    for (int i = 0; i < n; i++)
	    {
	        nK = lcm(nK, a[i]);
	    }
	    return nK;
	}
}
